// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

import StockItem from "../views/items/StockItem";
import { ScrollBarEnhance } from "../ui/ScrollBarEnhance";

const {ccclass, property} = cc._decorator;

@ccclass
export default class ThsListView extends cc.Component {

    @property(cc.Prefab)
    itemPrefab: cc.Prefab = null;

    @property(cc.Node)
    content: cc.Node = null;
    
    @property(ScrollBarEnhance)
    verSlider: ScrollBarEnhance = null;

    @property(ScrollBarEnhance)
    horSlider: ScrollBarEnhance = null;

    scrollview: cc.ScrollView = null;

    @property(cc.Integer)
    frameCount: number = 0;
    // LIFE-CYCLE CALLBACKS:

    _initListPos: cc.Vec2 = cc.v2(0,0);

    _initCount: number = 0;

    _lastStartIndex: number = null;

    _itemArray: StockItem[] = [];

    _data: any = [];

    _nodeWidth: number = 0;
    _nodeHeight: number = 0;
    _rawCount: number = 0;

    //需要渲染的列数
    _drawLine: number = 0;
    //需要渲染的行
    _drawRaw: number = 0;
    //本帧需要渲染的总数量
    _drawTotalCount: number = 0;

    onLoad () {
        this._initCount = 0;
        let node = cc.instantiate(this.itemPrefab);
        this.content.addChild(node);
        node.opacity = 0;
        let item = node.getComponent(StockItem);
        this._itemArray.push(item);
        this._nodeHeight = node.height;
        this._nodeWidth = node.width;
        this.scrollview = this.node.getComponent(cc.ScrollView);
        this._initListPos = cc.v2(this.content.x, this.content.y);

        this._drawRaw = Math.floor(this.scrollview.node.width / this._nodeWidth) + 1;
        this._drawLine = Math.floor(this.scrollview.node.height / this._nodeHeight) + 1;
    }

    start () {

    }


    setData (array : any, count: number) {
        this.clearData();
        this._data = array.slice();
        this.content.height = this._nodeHeight * count + 8;
        this._rawCount = count;
        let lineCount = Math.floor(array.length / this._rawCount);
        this.content.width = this._nodeWidth * lineCount + 8;
        this.verSlider.refresh(0);
        this._lastStartIndex = null;
    }

    pushData (array : any) {
        this._data = this._data.concat(array);
        let lineCount = Math.floor(this._data.length / this._rawCount);
        this.content.width = this._nodeWidth * lineCount + 8;
        this.horSlider.refresh(0);
        this._lastStartIndex = null;
    }

    clearData () {
        for (let index = 0; index < this._itemArray.length; index++) {
            const item = this._itemArray[index];
            item.node.opacity = 0;
            this._data = [];
            this._drawTotalCount = 0;
        }
    }

    //计算需要渲染的数据
    calcDrawData () {
        if (this._data.length == 0) return [];
        let newPos = this.content.position;
        let disX = this._initListPos.x - newPos.x;
        let disY = newPos.y - this._initListPos.y;

        let startRaw = Math.floor(disX / this._nodeWidth);
        let startLine = Math.floor(disY / this._nodeHeight);
        let startIndex = startRaw * this._rawCount + startLine;

        if (this._lastStartIndex == startIndex) return [];
        this._lastStartIndex = startIndex;

        let endRaw = startRaw + this._drawRaw;
        let endLine = startLine + this._drawLine;

        let drawLindex = 0;
        let drawData = [];
        for (let index = 0; index < this._data.length; index++) {
            let line = index % this._rawCount;
            let raw = Math.floor(index / this._rawCount);
            if (raw >= startRaw && raw <= endRaw && line >= startLine && line <= endLine) {
                let data = this._data[index];
                drawLindex++;
                drawData.push({raw: raw, line: line, data: data});
            }
        }
        this._drawTotalCount = drawLindex;
        return drawData;
    }

    drawList (drawData: any) {
        for (let index = 0; index < drawData.length; index++) {
            const drawItem = drawData[index];
            let line = drawItem.line;
            let raw = drawItem.raw;
            let data = drawItem.data;
            let item = this._itemArray[index];
            if (item) {
                let node = item.node;
                node.opacity = 255;
                item.setItemData(data);
                node.x = raw * this._nodeWidth + this._nodeWidth / 2 + 4;
                node.y = line * this._nodeHeight + this._nodeHeight / 2 + 4;
                node.y = -node.y;
            }
        }
    }

    update () {
        let drawData = this.calcDrawData();
   
        if (this._initCount < this._drawTotalCount) {
            for (let index = 0; index < this.frameCount; index++) {
                let node = cc.instantiate(this.itemPrefab);
                this.content.addChild(node);
                node.opacity = 0;
                let item = node.getComponent(StockItem);
                this._itemArray[this._initCount] = item;
                this._lastStartIndex = null;
                this._initCount++;
                if (this._initCount >= this._drawTotalCount) break;
            }
        }
        if (drawData.length > 0) {
            this.drawList(drawData);
        }
    }
}
